package handler

import (
	"context"
	"strings"

	paho "github.com/eclipse/paho.mqtt.golang"
	"github.com/zeromicro/go-zero/core/logx"
)

// TopicHandler 定义主题处理器接口
// 不同的主题可以有不同的处理器实现
// 用于处理订阅到的消息

type TopicHandler interface {
	// HandleMessage 处理订阅到的消息
	// ctx: 上下文
	// client: MQTT客户端
	// msg: 接收到的消息
	HandleMessage(ctx context.Context, client paho.Client, msg paho.Message)
}

// TopicHandlerFunc 是一个函数类型，可以转换为TopicHandler

type TopicHandlerFunc func(ctx context.Context, client paho.Client, msg paho.Message)

// HandleMessage 实现TopicHandler接口
func (f TopicHandlerFunc) HandleMessage(ctx context.Context, client paho.Client, msg paho.Message) {
	f(ctx, client, msg)
}

// TopicHandlerRegistry 主题处理器注册表
// 用于管理和获取不同主题的处理器


type TopicHandlerRegistry struct {
	// handlers 存储主题与处理器的映射
	handlers map[string]TopicHandler
	// defaultHandler 默认处理器，当没有匹配的处理器时使用
	defaultHandler TopicHandler
}

// NewTopicHandlerRegistry 创建一个新的主题处理器注册表
func NewTopicHandlerRegistry() *TopicHandlerRegistry {
	return &TopicHandlerRegistry{
		handlers:       make(map[string]TopicHandler),
		defaultHandler: DefaultTopicHandler{},
	}
}

// RegisterHandler 注册一个主题处理器
// topic: 主题名称，可以包含通配符
// handler: 主题处理器
func (r *TopicHandlerRegistry) RegisterHandler(topic string, handler TopicHandler) {
	r.handlers[topic] = handler
}

// RegisterHandlerFunc 注册一个处理器函数
// topic: 主题名称，可以包含通配符
// handlerFunc: 处理器函数
func (r *TopicHandlerRegistry) RegisterHandlerFunc(topic string, handlerFunc func(ctx context.Context, client paho.Client, msg paho.Message)) {
	r.handlers[topic] = TopicHandlerFunc(handlerFunc)
}

// GetHandler 获取匹配给定主题的处理器
// topic: 主题名称
// 返回: 匹配的处理器，如果没有匹配的则返回默认处理器
func (r *TopicHandlerRegistry) GetHandler(topic string) TopicHandler {
	// 首先尝试精确匹配
	if handler, ok := r.handlers[topic]; ok {
		return handler
	}

	// 尝试通配符匹配
	for pattern, handler := range r.handlers {
		if matchTopic(pattern, topic) {
			return handler
		}
	}

	// 如果没有匹配的处理器，返回默认处理器
	return r.defaultHandler
}

// 设置默认处理器
func (r *TopicHandlerRegistry) SetDefaultHandler(handler TopicHandler) {
	r.defaultHandler = handler
}

// DefaultTopicHandler 默认主题处理器
// 当没有为特定主题注册处理器时使用

type DefaultTopicHandler struct {}

// HandleMessage 实现默认的消息处理逻辑
func (h DefaultTopicHandler) HandleMessage(ctx context.Context, client paho.Client, msg paho.Message) {
	// 简单地记录接收到的消息
	logx.WithContext(ctx).Infof("Received message from topic [%s]: %s", msg.Topic(), string(msg.Payload()))
}

// matchTopic 检查主题是否匹配给定的模式
// 支持MQTT的主题通配符: + (单级) 和 # (多级)
func matchTopic(pattern, topic string) bool {
	// 实现简化的主题匹配逻辑
	// 这里只处理基本的通配符匹配
	patternParts := strings.Split(pattern, "/")
	topicParts := strings.Split(topic, "/")

	if len(patternParts) != len(topicParts) {
		// 如果模式以#结尾，可以匹配任意多个后续级别
		if len(patternParts) > 0 && patternParts[len(patternParts)-1] == "#" {
			patternParts = patternParts[:len(patternParts)-1]
		} else {
			return false
		}
	}

	for i := 0; i < len(patternParts); i++ {
		if patternParts[i] == "#" {
			// # 可以匹配任意数量的级别
			return true
		} else if patternParts[i] == "+" {
			// + 只匹配一个级别
			continue
		} else if patternParts[i] != topicParts[i] {
			return false
		}
	}

	return true
}